﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace Quiz.LINQData
{
    [Table(Name="Fragen")]
    class Frage
    {
        #region Member
            private string _fragetext;
            private DateTime _aDatum;
            private int _kategorieID;
            private int _erstellerID;
            private int _frageID;
            private Random _randomID;
            private Antwort _defaultAntwort;
            //Notwendig für Fremdschlüsselspalten um auf diese zugreifen zu können (Hier die Kategorie), es gibt zusätzlich noch ein Property
            private EntityRef<Kategorie> _kategorie;
            private EntityRef<Ersteller> _ersteller;
            private EntitySet<Antwort> _antworten;
        #endregion


        #region Properties
            /// <summary>
            /// Die FrageID selbst (Unique)
            /// Wichtig! Das IsPrimary, IsDBGenrated und TdType gesetzt sind. Bei den Primärschlüsselspalten.
            /// </summary>
            [Column(IsPrimaryKey = true, IsDbGenerated= true, DbType="INT NOT NULL IDENTITY", Name = "FrageID", Storage = "_frageID")]
            public int FrageID
            {
                get { return _frageID; }
                set { _frageID = value; }
            }

            /// <summary>
            /// setzt bzw. gibt den Fragetext zurück
            /// </summary>
            [Column(Name="Frage", Storage="_fragetext")]
            public string Fragetext
            {
                get { return _fragetext; }
                set { _fragetext = value; }
            }

            /// <summary>
            /// Das Erstelldatum der Frage
            /// </summary>
            [Column(Name="ADatum", Storage="_aDatum")]
            public DateTime ADatum
            {
                get { return _aDatum; }
                set { _aDatum = value; }
            }

            /// <summary>
            /// Die KategorieId die der Frage zugeordnet ist
            /// </summary>
            [Column(Name="KategorieID", Storage="_kategorieID")]
            public int KategorieID
            {
                get { return _kategorieID; }
                set{ _kategorieID = value;}
            }

            /// <summary>
            /// Die ErstellerID die der Frage zugeordnet ist.
            /// </summary>
            [Column(Name = "ErstellerID", Storage = "_erstellerID")]
            public int ErstellerID
            {
                get { return _erstellerID; }
                set { _erstellerID = value; }
            }

            /// <summary>
            /// Gibt die "Kategorieklasse" zurück die zu dieser ID hinterlegt wurde in einer anderen Tabelle
            /// Ist dazu da um auf Fremdschlüsselspalten zugreifen zu können, wo nur ein Wert hinterlegt ist.
            /// Da Ich bereits ein Property für die KategorieID angeben habe, muss ich bei ThisKey auf dieses Property verweisen und nicht auf mein Member
            /// </summary>
            [Association(Storage = "_kategorie", ThisKey = "KategorieID")]
            public  Kategorie Kategorie
            {
                get { return this._kategorie.Entity; }
                set { this._kategorie.Entity = value; }
            }

            /// <summary>
            /// Gibt die "Erstellerklasse" zurück die zu dieser ID hinterlegt wurde in einer anderen Tabelle
            /// </summary>
            [Association(Storage = "_ersteller", ThisKey = "ErstellerID")]
            public Ersteller Ersteller
            {
                get { return this._ersteller.Entity; }
                set { this._ersteller.Entity = value; }
            }

            /// <summary>
            /// Gibt alle Antworten zurück die für diese Frage hinterlegt wurden in einer Liste aus Antwort
            /// </summary>
            [Association(OtherKey = "FrageID", Storage = "_antworten")]
            public ICollection<Antwort> Antworten
            {
                get { return this._antworten; }
                set { this._antworten.Assign(value); }
            }
        #endregion

        #region Konstruktor
            public Frage()
            {
                _randomID = new Random();
                _defaultAntwort = new Antwort();
                _antworten = new EntitySet<Antwort>();
            }
        #endregion

        #region Functions/Subs
            /// <summary>
            /// Kümmert sich darum, das für alle zur verfügung stehenden Antworten die Nummerierung gesetzt wird z.B. "1." oder "2.", ....
            /// </summary>
            public void AddRandomAntwortNummerierung()
            {
                List<int> numbers = new List<int>();
                //Sollte sich noch die Defaultanwort in der Liste befinden diese aus der List entfernen
                Antworten.Remove(_defaultAntwort);

                //Alle Antworten durchgehen und für jede Antwort eine neue "Nummerierung setzten"
                foreach (Antwort antwort in Antworten)
                {
                    int neueNummer = int.MinValue;
                    //Solange While durchlaufen bis eine Nummer gefunden wurde die noch nicht der Liste hinzugefügt wurde
                    while (numbers.Count < (Antworten.Count + 1))
                    {
                        int randomNumber = _randomID.Next(1, Antworten.Count + 1);
                        if (!numbers.Contains(randomNumber))
                        {
                            numbers.Add(randomNumber);
                            neueNummer = randomNumber;
                            break;
                        }
                    }

                    //Wenn eine Neue Nummer gefunden wurde, diese der Antwort zuweisen.
                    antwort.AntwortPos = neueNummer;
                }

                //Einen Standardantworttext für "Überspringen" der Antwortliste hinzufügen
                AddDefaultAntwortNext();
            }

            /// <summary>
            /// Fürgt zur aktuellen Antwortliste noch den "defaultwert" hinzu das diese Frage übersprungen werden soll.
            /// </summary>
            private void AddDefaultAntwortNext()
            {
                _defaultAntwort.AntwortID = int.MinValue;
                _defaultAntwort.Antworttext = "Nächste Frage";
                _defaultAntwort.FrageID = this.FrageID;
                _defaultAntwort.Richtig = false;
                _defaultAntwort.AntwortPos = Antworten.Count + 1;
                //Die Defaultantwort der Liste hinzufügen
                this.Antworten.Add(_defaultAntwort);
            }

        #endregion
    }
}
